<?php
/**
 * MoneyModel.class.php
 * 现金交易模型
 *
 * @author  王中艺
 * @date    2016-11-08
 */

namespace Wechat\Model;

class MoneyModel extends BaseModel {

    //重定义数据表
    protected   $trueTableName  = 't_money';

    /**
     * 创建订单
     * @param   $userId     用户ID
     * @param   $goodsType  商品类型
     * @param   $goodsId    商品ID
     * @param   $amount     支付金额
     * @param   $payCate    交易渠道
     * @param   $couponCode 优惠码
     * @param   $payScore   支付幸福豆
     * @return  $payId
     */
    function createPay($userId, $goodsType, $goodsId, $amount, $remark, $payCate = 1, $codeId = 0){
        $payInfo  = array(
            'user_id'   => $userId,
            'trade_no'  => date('YmdHis').rand(1000, 9999),
            'goods_type'    => $goodsType,
            'goods_id'  => $goodsId,
            'amount'    => $amount,
            'create_time'   => time(),
            'status'    => 2,
            'pay_cate'  => $payCate,
            'remark'    => $remark,
            'code_id'   => $codeId
        );

        $payId     = $this->add($payInfo);
        $payInfo['id']  = $payId;
        return $payInfo;
    }

    /**
     * 支付成功(回调接口调用)
     * @param   $payId
     * @return  boolean
     */
    function successPay($payId){
        $payInfo    = $this->where('id = %d', $payId)->find();
        if(!$payInfo){
            $this->errMsg   = '未找到相关订单!';
            $this->payError($payInfo);
            return false;
        }
        if($payInfo['status'] != 2){
            $this->errMsg   = '该订单不是待支付状态!';
            $this->payError($payInfo);
            return false;
        }
        
        $this->startTrans();

        //支付成功回写相关表
        switch($payInfo['goods_type']){
            //购买课程
            case 1:
                $result     = D('Course')->paySuccess($payInfo);
                if(!$result){
                    $this->errMsg   = '支付回写t_user_course表失败!';
                    $this->payError($payInfo);
                    $this->rollback();
                    return false;
                }
            break;

            //购物车购买
            case 4:
                $result     = D('ShopCart')->paySuccess($payInfo);
                if($result === false){
                    $this->errMsg   = D('ShopCart')->errMsg;
                    $this->payError($payInfo);
                    $this->rollback();
                    return false;
                }
            break;

            //vip购买
            case 5:
                $vipInfo    = C('VIP_TYPE.'.$payInfo['goods_id']);
                $result     = D('User')->giveVip($payInfo['user_id'], 1, $vipInfo['time_desc']);
                if($result === false){
                    $this->errMsg   = 'VIP信息更改失败';
                    $this->payError($payInfo);
                    $this->rollback();
                    return false;
                }
            break;

            default: break;
        }

        //优惠码使用
        if($payInfo['code_id']){
            $ret    = D('Coupon')->useCouponCode($payInfo['code_id'], $payInfo['user_id'], false, true);
            if($ret === false){
                write_log('./Log/error_coupon_code', 'Coupon Code use error!', D('Coupon')->errMsg);
            }
        }

        //订单信息更新
        $payInfo['achive_time'] = time();
        $payInfo['status']  = 9;
        if(!$this->save($payInfo)){
            $this->rollback();
            $this->errMsg   = '数据更新失败!(t_money)';
            $this->payError($payInfo);
            return false;
        }

        $this->commit();
        return true;

        //优惠码处理
        //To do...
        
        //积分支付处理
        //To do...

        // //有效支付金额参与返利及分成
        // if($payInfo['amount'] > 0){
        //     //购买课程返利
        //     $score  = ceil($payInfo['amount']*5);
        //     $dScore     = D('Score');
        //     $result     = $dScore->addScore($payInfo['user_id'], 1, $payId, $score, '消费返利', true);
        //     if($result === false){
        //         $this->errMsg   = $dScore->errMsg;
        //         $this->rollback();
        //         return false;
        //     }

        //     //关系链返利
        //     $deductAmount     = $this->relaRebate($payInfo);
        //     if($deductAmount === false){
        //         $this->rollback();
        //         return false;
        //     }
        // }
    }

    /**
     * 成功支付后续操作
     * @param   $payInfo
     * @return  boolean
     */
    function successPaySequel($moneyInfo){
        if($moneyInfo['amount'] > 0){
            //关系链返利处理
            $result   = $this->relaRebate($moneyInfo);
            if($reslut === false){
                return false;
            }
            //用户消费积分获取
            $score  = ceil($moneyInfo['amount'] * 5);
            $goodsId   = 1;
            $remark     = '消费返利';
            $result = D('Score')->addScore(
                $moneyInfo['user_id'],
                $goodsId,
                $moneyInfo['id'],
                $score,
                $remark
            );
            if($result === false){
                $this->errMsg   = '积分添加失败';
                return false;
            }
        }
    }

    /**
     * 关系链返利
     * @param   $payInfo    支付信息
     * @return  $deductAmount   总返利金额
     */
    function relaRebate($payInfo){
        //检测物品是否参与分成
        $deductGoods    = array(1, 4, 5);
        if(!in_array($payInfo['goods_type'], $deductGoods)){
            return false;
        }

        //消费者关系链返利
        $relaInfo   = M('t_user_relative', null)->where('user_id = %d', $payInfo['user_id'])->find();
        foreach($relaInfo as $key=>$val){
            if($val == -1)  
                unset($relaInfo[$key]);
        }
        unset($relaInfo['user_id']);
        $relaInfo   = array_reverse($relaInfo);;
        $level  = 0;
        $scores     = [];
        $deducts    = [];
        $deductAmount   = 0;
        $rebate     = [0.3, 0.12, 0.06, 0.1, 0.1, 0.1];
        $users      = [];
        $originId   = 0;
        $expandId   = false;
        $deanId     = false;
        foreach($relaInfo as $key => $val){
            switch($key){
                case 'parent_id':
                    if($val != 0){
                        //上级家长返利积分
                        $score  = ceil($payInfo['amount']*10);
                        $scores[]   = array(
                            'user_id'   => $val,
                            'goods_type'   => 8,
                            'goods_id'  => $payInfo['id'],
                            'score' => $score,
                            'create_time'   => time()
                        );
                        D('Score')->addScore($val, 8, $payInfo['id'], $score, '下级用户购买返利');
                        $users[$val]['score']   = $score;
                        $level++;
                    }
                    $val    = $val == 0 ? $payInfo['user_id'] : $val;
                    $originId   = $val;
                break;

                //老师返利业绩记录
                case 'teacher_id':
                    // $rate   = $rebate[$level];
                    // $val    = $val == 0 ? $payInfo['user_id'] : $val;
                    // $deducts[]   = array(
                    //     'user_id'   => $val,
                    //     'pay_id'    => $payInfo['id'],
                    //     'role_id'   => 3,
                    //     'achive'    => $payInfo['amount']*$rate,
                    //     'amount'    => 0,
                    //     'origin_id' => $originId,
                    //     'percent'   => $rate,
                    //     'create_time'   => time()
                    // );
                    $val    = $val == 0 ? $payInfo['user_id'] : $val;
                    $originId   = $val;
                break;

                //推销员返利现金
                case 'expand_id':
                    $rate   = $rebate[$level];
                    $val    = $val == 0 ? $payInfo['user_id'] : $val;
                    $deducts[]   = array(
                        'user_id'   => $val,
                        'money_id'    => $payInfo['id'],
                        'amount'    => $payInfo['amount']*$rate,
                        'percent'   => $rate,
                        'origin_id' => $originId,
                        'create_time'   => time()
                    );
                    $users[$val]['amount']  = $payInfo['amount']*$rate;
                    $deductAmount   += $payInfo['amount']*$rate;
                    $level  = $level + 2;
                    $originId   = $val;
                    $expandId   = $val;
                break;

                //院长返利现金
                case 'dean_id':
                    $rate   = $rebate[$level];
                    $val    = $val == 0 ? $payInfo['user_id'] : $val;
                    $deducts[]   = array(
                        'user_id'   => $val,
                        'money_id'    => $payInfo['id'],
                        'amount'    => $payInfo['amount']*$rate,
                        'percent'   => $rate,
                        'origin_id' => $originId == 0 ? $val : $originId,
                        'create_time'   => time()
                    );
                    $users[$val]['amount']  = $payInfo['amount']*$rate;
                    $deductAmount   += $payInfo['amount']*$rate;
                    $deanId     = $val;
                break;
            }
        }

        // //记录入库
        // if($scores){
        //     if(!M('t_score', null)->addAll($scores)){
        //         $this->errMsg   = '数据插入失败!(t_log_score)';
        //         return false;
        //     }
        // }
        if($deducts){
            if(!M('t_deduct', null)->addAll($deducts)){
                $this->errMsg   = '数据插入失败!(t_log_deduct)';
                return false;
            }
        }

        //用户信息更改
        foreach($users as $userId => $user){
            $amount     = $user['amount'] ? $user['amount'] : 0;
            $score      = $user['score'] ? $user['score'] : 0;
            $this->execute(
                'update t_user set amount = amount + %.2f, score = score + %d, wallet = wallet + %.2f where id = %d',
                $amount,
                $score,
                $amount,
                $userId
            );
            S('user_info_'.$userId, null);
        }

        //推销员B、C金额加入院长钱包
        if($expandId && $users[$expandId]['amount'] && $deanId){
            $expandInfo     = D('User')->getUserInfo($expandId);
            if(($expandInfo['role_id'] == 103 || $expandInfo['role_id'] == 104)){
                $deanInfo   = D('User')->getUserInfo($deanId);
                $deanInfo['amount'] += $users[$expandId]['amount'];
                $deanInfo['wallet'] += $users[$expandId]['amount'];
                D('User')->updateUserInfo($deanId, $deanInfo);
            }
        }

        //回写订单分成信息
        $payInfo['deduct']  = $deductAmount;
        $payInfo['status']  = 1;
        return $this->save($payInfo);
    }
    

    /**
     * 支付失败
     */
    function payError($moneyInfo, $attach = ''){
        $content    = sprintf(
            "Time:\t[%s]\nMoneyInfo:\t%s\nErrMsg:\t%s\n\n", 
            date('Y-m-d H:i:s'), 
            json_encode($moneyInfo),
            $this->errMsg
        );
        if($attach) $attach     = '['.$attach.']';
        file_put_contents('./Log/wxpay_error.log', $content.$attach, FILE_APPEND);
    }

    /**
     * 添加订单记录
     * @param   $userId
     * @param   $tradeNo
     * @param   $goodsType
     * @param   $goodsId
     * @param   $amount
     */
    function addMoneyInfo($userId, $tradeNo, $goodId,$goodsType, $amount){
        $moneyInfo  = array(
            'user_id'   => $userId,
            'trade_no'  => $tradeNo,
            'goods_type'    => $goodsType,
            'goods_id'  => $goodId,
            'amount'    => $amount,
            'create_time'   => time(),
            'achive_time'   => time(),
            'pay_type'  => 1,
            'status'    => 1
        );

        $moneyId    = $this->add($moneyInfo);
        $moneyInfo['id']    = $moneyId;
        return $moneyInfo;
    }
}
